package com.design.framework.dataSource;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 面向切面切换数据库
 * 
 * @author JohnDeng
 * @dataTime 2018年3月26日下午4:12:21
 *
 */
@Component
@Aspect
public class DataSourceAop {
	protected Logger logger = Logger.getLogger(getClass());

	@Pointcut("@annotation(com.design.framework.dataSource.DataSource)")
	public void dataSourceBefore() {

	}

	/**
	 * 根据数据源id直接匹配名称，若没有使用注解默认调用read数据
	 * 
	 * @author JohnDeng
	 * @date 2018年8月14日下午2:54:32
	 * @param jp
	 */
	@Before("dataSourceBefore()")
	public void Before(JoinPoint jp) {
		/*
		 * logger.debug("------------------方法执行之前------------------");
		 * logger.debug("------------------方法名：" + jp.getSignature().getName() +
		 * "------------------"); logger.debug("------------------方法名："
		 * +getMthodTableType(jp) + "------------------");
		 */
		if (getMthodTableType(jp).equals(DataSourceType.dataSourceRead.toString())) {
			DynamicDataSourceHolder.setDataSource(DataSourceType.dataSourceRead.toString());
		} else if (getMthodTableType(jp).equals(DataSourceType.dataSourceWrite.toString())) {
			DynamicDataSourceHolder.setDataSource(DataSourceType.dataSourceWrite.toString());
		} else {
			DynamicDataSourceHolder.setDataSource(DataSourceType.dataSourceRead.toString());
		}
	}

	/**
	 * 获取DataSource注解的type
	 * 
	 * @param joinPoint
	 * @return
	 */
	private String getMthodTableType(JoinPoint joinPoint) {
		String targetName = joinPoint.getTarget().getClass().getName();
		String methodName = joinPoint.getSignature().getName();
		Object[] arguments = joinPoint.getArgs();
		Class<?> targetClass;
		String dbType = "";
		try {
			targetClass = Class.forName(targetName);
			Method[] methods = targetClass.getMethods();
			for (Method method : methods) {
				if (method.getName().equals(methodName)) {
					Class<?>[] clazzs = method.getParameterTypes();
					if (clazzs.length == arguments.length) {
						dbType = method.getAnnotation(DataSource.class).dbType().toString();
						break;
					}
				}
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return dbType;
	}

}
